{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "96ff2e49",
   "metadata": {},
   "source": [
    "### 加载数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "1e8b6ff1",
   "metadata": {},
   "outputs": [],
   "source": [
    "dir_datas = '/home3/junkang/JJK/tpgn-paper-and-codes/datas_files'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "cd1a890d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.6224593312018546\n",
      "0.5000000000000001\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "np.random.seed(2025)\n",
    "\n",
    "# sigmoid函数及其反函数\n",
    "def sigmoid(x):\n",
    "    return 1 / (1 + np.exp(-x))\n",
    "\n",
    "def sigmoid_inv(x):\n",
    "    return np.log(x / (1 - x))\n",
    "\n",
    "# 示例\n",
    "x = 0.5\n",
    "print(sigmoid(x))  # 输出：0.6224593312018546\n",
    "print(sigmoid_inv(sigmoid(x)))  # 输出：0.49999999999999994"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "df388449",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>OT</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>428.1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>428.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>427.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>430.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>432.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52691</th>\n",
       "      <td>433.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52692</th>\n",
       "      <td>439.6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52693</th>\n",
       "      <td>435.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52694</th>\n",
       "      <td>433.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52695</th>\n",
       "      <td>436.5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>52696 rows × 1 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "          OT\n",
       "0      428.1\n",
       "1      428.0\n",
       "2      427.6\n",
       "3      430.0\n",
       "4      432.2\n",
       "...      ...\n",
       "52691  433.0\n",
       "52692  439.6\n",
       "52693  435.2\n",
       "52694  433.9\n",
       "52695  436.5\n",
       "\n",
       "[52696 rows x 1 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "def get_seq_datas(fname_csv, dir_datas=dir_datas, col_target=['OT']):\n",
    "    \"\"\"\n",
    "    \"\"\"\n",
    "    fname_csv = os.path.join(dir_datas, fname_csv)\n",
    "    df = pd.read_csv(fname_csv)\n",
    "    df = df.dropna()\n",
    "    df = df[col_target]\n",
    "    \n",
    "    return df\n",
    "\n",
    "df = get_seq_datas('weather.csv')\n",
    "df\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "248a21c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 52528/52528 [00:00<00:00, 54976.77it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([16, 168, 1])\n"
     ]
    }
   ],
   "source": [
    "# 数据集Dataset准备\n",
    "import torch\n",
    "torch.manual_seed(2025)\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.utils.data import Dataset\n",
    "from tqdm import tqdm\n",
    "\n",
    "class MyDataset(Dataset):\n",
    "    def __init__(self, df, seq_len = 168):\n",
    "        self.df = df\n",
    "        self.seq_len = seq_len\n",
    "        self.datas = self.get_seq_datas()\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.datas)\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        \"\"\"\n",
    "        \"\"\"\n",
    "        # 获取数据\n",
    "        data = self.datas[idx]\n",
    "\n",
    "        return torch.tensor(data, dtype=torch.float32)\n",
    "        \n",
    "\n",
    "    def get_seq_datas(self):\n",
    "        \"\"\"\n",
    "        \"\"\"\n",
    "        # 数据预处理\n",
    "        # 归一化\n",
    "        # df = self.df.copy()\n",
    "        # df = (df - df.min()) / (df.max() - df.min())\n",
    "\n",
    "        datas = []\n",
    "        for i in tqdm(range(len(df) - self.seq_len)):\n",
    "            seq = df.iloc[i:i + seq_len].values\n",
    "            datas.append(seq)\n",
    "        return np.array(datas)\n",
    "\n",
    "# 测试数据集\n",
    "\n",
    "seq_len = 168\n",
    "batch_size = 16\n",
    "dataset = MyDataset(df.iloc[:320], seq_len)\n",
    "dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)\n",
    "\n",
    "# 测试数据集示例\n",
    "for data in dataloader:\n",
    "    print(data.shape)\n",
    "    break\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "fead959a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(42157, 10539)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_p = 0.2\n",
    "nums_test = int(len(df) * test_p)\n",
    "# 划分训练集和测试集\n",
    "train_df = df.iloc[:-nums_test]\n",
    "test_df = df.iloc[-nums_test:]\n",
    "\n",
    "len(train_df), len(test_df)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "df06cccc",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/52528 [00:00<?, ?it/s]"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 52528/52528 [00:01<00:00, 49185.79it/s]\n",
      "100%|██████████| 52528/52528 [00:00<00:00, 52743.28it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([32, 168, 1])\n"
     ]
    }
   ],
   "source": [
    "dataset_train = MyDataset(train_df, seq_len)\n",
    "dataset_test = MyDataset(test_df, seq_len)\n",
    "batch_size = 32\n",
    "dataloader_train = DataLoader(dataset_train, batch_size=batch_size, shuffle=True)\n",
    "dataloader_test = DataLoader(dataset_test, batch_size=batch_size, shuffle=False)\n",
    "# 测试数据集示例\n",
    "for data in dataloader_test:\n",
    "    print(data.shape)\n",
    "    break\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "38401ac7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([32, 167, 1])\n",
      "torch.Size([32, 167, 1])\n"
     ]
    }
   ],
   "source": [
    "for data in dataloader_test:\n",
    "    print(data[:, :-1, :].shape)\n",
    "    print(data[:, 1:, :].shape)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89951f97",
   "metadata": {},
   "source": [
    "### 模型定义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6ebffbd3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "c6b44230",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 168, 32])\n"
     ]
    }
   ],
   "source": [
    "class PGN_native(nn.Module):\n",
    "    def __init__(self, input_size = 1, hidden_size = 32, seq_len = 168):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            input_size: The number of expected features in the input `x`\n",
    " |          hidden_size: The number of features in the hidden state `h`\n",
    "        \"\"\"\n",
    "        super(PGN_native, self).__init__()\n",
    "        \n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.window_size = seq_len - 1\n",
    "\n",
    "        self.hidden_MLP = nn.Conv1d(\n",
    "            in_channels = input_size,\n",
    "            out_channels = hidden_size,\n",
    "            kernel_size = self.window_size,\n",
    "            stride = 1,\n",
    "            bias=True)\n",
    "        \n",
    "        # 卷积层的权重参数可以表示为一个四维张量，其形状为 (out_channels, in_channels, kernel_size)。\n",
    "        # 在这个例子中，权重参数的形状为 (2 * hidden_size, input_size + hidden_size, 1)。\n",
    "        # 这个权重参数可以看作是由两个部分组成的：前半部分用于计算门控状态，后半部分用于计算候选状态。\n",
    "        self.gate = nn.Conv1d(\n",
    "            in_channels = input_size + hidden_size, \n",
    "            out_channels = 2 * hidden_size,   # 2 * hidden_size 是为了同时计算门控状态G和候选状态H^\n",
    "            kernel_size = 1, \n",
    "            stride = 1, bias=True)\n",
    "        \n",
    "        self.gate_values = None  # 保存门控状态，用于后续分析\n",
    "    \n",
    "    def forward(self, X):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            X: A tensor of shape `(B, L, input_size)`\n",
    "        \"\"\"\n",
    "        # 将 序列X 的序列左边填充 window_size 个 零向量得到 padding_X: (B, window_size + L, input_size)\n",
    "        padding = torch.zeros(X.shape[0], self.window_size, X.shape[2]).to(X.device)\n",
    "        padding_X = torch.cat([padding, X], dim=1)\n",
    "        # 计算隐藏状态H: (B, L, hidden_size * 2)\n",
    "        padding_X = padding_X.permute(0, 2, 1)  # (B, input_size, window_size + L)\n",
    "        H = self.hidden_MLP(padding_X[:, :, :-1]).permute(0, 2, 1)\n",
    "        # 计算门控状态G和候选状态H_hat: (B, L, hidden_size)\n",
    "        gate_status  = self.gate( torch.cat([X, H], dim=-1).permute(0, 2, 1) )\n",
    "        G, H_hat = torch.split(gate_status.permute(0, 2, 1), self.hidden_size, dim=-1)\n",
    "        G = torch.sigmoid(G)\n",
    "        H_hat = torch.tanh(H_hat)\n",
    "        # 计算输出(状态的选择和融合)\n",
    "        Out = G * H + (1 - G) * H_hat\n",
    "\n",
    "        self.gate_values = G  # 保存门控状态，用于后续分析\n",
    "        return Out, G\n",
    "\n",
    "# 定义模型\n",
    "input_size = 1\n",
    "hidden_size = 32\n",
    "seq_len = 168\n",
    "model = PGN_native(input_size, hidden_size, seq_len)\n",
    "# 测试模型\n",
    "X = torch.randn(4, seq_len, input_size)\n",
    "y, _ = model(X)\n",
    "print(y.shape)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "56f5c8a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 168, 32])\n"
     ]
    }
   ],
   "source": [
    "class PGN_withPosEmb(nn.Module):\n",
    "    def __init__(self, input_size = 1, hidden_size = 32, seq_len = 168):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            input_size: The number of expected features in the input `x`\n",
    " |          hidden_size: The number of features in the hidden state `h`\n",
    "        \"\"\"\n",
    "        super(PGN_withPosEmb, self).__init__()\n",
    "        \n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.window_size = seq_len - 1\n",
    "        self.seq_len = seq_len\n",
    "\n",
    "        self.posEmb = nn.Embedding(seq_len, input_size)\n",
    "\n",
    "        self.hidden_MLP = nn.Conv1d(\n",
    "            in_channels = input_size,\n",
    "            out_channels = hidden_size,\n",
    "            kernel_size = self.window_size,\n",
    "            stride = 1,\n",
    "            bias=True)\n",
    "        \n",
    "        # 卷积层的权重参数可以表示为一个四维张量，其形状为 (out_channels, in_channels, kernel_size)。\n",
    "        # 在这个例子中，权重参数的形状为 (2 * hidden_size, input_size + hidden_size, 1)。\n",
    "        # 这个权重参数可以看作是由两个部分组成的：前半部分用于计算门控状态，后半部分用于计算候选状态。\n",
    "        self.gate = nn.Conv1d(\n",
    "            in_channels = input_size + hidden_size, \n",
    "            out_channels = 2 * hidden_size,   # 2 * hidden_size 是为了同时计算门控状态G和候选状态H^\n",
    "            kernel_size = 1, \n",
    "            stride = 1, bias=True)\n",
    "        \n",
    "        self.gate_values = None  # 保存门控状态，用于后续分析\n",
    "    \n",
    "    def forward(self, X):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            X: A tensor of shape `(B, seq_len, input_size)`\n",
    "        \"\"\"\n",
    "        # pos Embedding\n",
    "        pos_idx = torch.arange(self.seq_len, requires_grad =False).unsqueeze(0)  # (1, seq_len,)\n",
    "        pos_idx = pos_idx.expand(X.shape[0], -1).to(X.device)  # (B, seq_len,)\n",
    "        pos_idx = self.posEmb(pos_idx)  # (B, seq_len, input_size)\n",
    "        X = X + pos_idx  # (B, seq_len, input_size)\n",
    "\n",
    "        # 将 序列X 的序列左边填充 window_size 个 零向量得到 padding_X: (B, window_size + L, input_size)\n",
    "        padding = torch.zeros(X.shape[0], self.window_size, X.shape[2]).to(X.device)\n",
    "        padding_X = torch.cat([padding, X], dim=1)\n",
    "        # 计算隐藏状态H: (B, L, hidden_size * 2)\n",
    "        padding_X = padding_X.permute(0, 2, 1)  # (B, input_size, window_size + L)\n",
    "        H = self.hidden_MLP(padding_X[:, :, :-1]).permute(0, 2, 1)\n",
    "        # 计算门控状态G和候选状态H_hat: (B, L, hidden_size)\n",
    "        gate_status  = self.gate( torch.cat([X, H], dim=-1).permute(0, 2, 1) )\n",
    "        G, H_hat = torch.split(gate_status.permute(0, 2, 1), self.hidden_size, dim=-1)\n",
    "        G = torch.sigmoid(G)\n",
    "        H_hat = torch.tanh(H_hat)\n",
    "        # 计算输出(状态的选择和融合)\n",
    "        Out = G * H + (1 - G) * H_hat\n",
    "\n",
    "        self.gate_values = G  # 保存门控状态，用于后续分析\n",
    "        return Out, G\n",
    "\n",
    "# 定义模型\n",
    "input_size = 1\n",
    "hidden_size = 32\n",
    "seq_len = 168\n",
    "model = PGN_withPosEmb(input_size, hidden_size, seq_len)\n",
    "# 测试模型\n",
    "X = torch.randn(4, seq_len, input_size)\n",
    "y, _ = model(X)\n",
    "print(y.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e5d2a553",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([16, 168, 1])\n",
      "torch.Size([16, 168, 1])\n",
      "torch.Size([16, 168, 1])\n",
      "torch.Size([16, 168, 1])\n"
     ]
    }
   ],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "class SeqModel(nn.Module):\n",
    "    def __init__(self, input_size = 1, hidden_size = 32, seq_len = 168, type_core = 'png', is_png_with_posEmb = False):\n",
    "        super(SeqModel, self).__init__()\n",
    "        \n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.seq_len = seq_len\n",
    "        self.type_core = type_core\n",
    "\n",
    "        if type_core == 'png':\n",
    "            if is_png_with_posEmb:\n",
    "                self.core = PGN_withPosEmb(input_size, hidden_size, seq_len)\n",
    "            else:\n",
    "                self.core = PGN_native(input_size, hidden_size, seq_len)\n",
    "        elif type_core == 'lstm':\n",
    "            self.core = nn.LSTM(input_size, hidden_size, batch_first=True)\n",
    "        else:\n",
    "            self.core = nn.RNN(input_size, hidden_size, batch_first=True)\n",
    "        \n",
    "        self.out_layers = nn.Linear(hidden_size, 1)\n",
    "\n",
    "    def forward(self, X):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            X: A tensor of shape `(B, seq_len, input_size)`\n",
    "        \"\"\"\n",
    "        out, _ = self.core(X)\n",
    "        out = self.out_layers(out)\n",
    "        return out\n",
    "\n",
    "# 定义模型\n",
    "input_size = 1\n",
    "hidden_size = 32\n",
    "seq_len = 168\n",
    "\n",
    "# 测试模型\n",
    "batch_size = 16\n",
    "X = torch.randn(batch_size, seq_len, input_size)\n",
    "\n",
    "model = SeqModel(input_size, hidden_size, seq_len, type_core = 'png', is_png_with_posEmb = False)\n",
    "y = model(X)\n",
    "print(y.shape)\n",
    "\n",
    "model = SeqModel(input_size, hidden_size, seq_len, type_core = 'png', is_png_with_posEmb = True)\n",
    "y = model(X)\n",
    "print(y.shape)\n",
    "\n",
    "model = SeqModel(input_size, hidden_size, seq_len, type_core = 'lstm', is_png_with_posEmb = False) \n",
    "y = model(X)\n",
    "print(y.shape)\n",
    "\n",
    "model = SeqModel(input_size, hidden_size, seq_len, type_core = 'rnn', is_png_with_posEmb = False)\n",
    "y = model(X)\n",
    "print(y.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79b1f604",
   "metadata": {},
   "source": [
    "### 模型训练过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2d469aad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义模型训练过程\n",
    "def train_model(model, dataloader, criterion, optimizer, num_epochs=10, device='cuda'):\n",
    "    \"\"\"\n",
    "    Args:\n",
    "        model: The model to train\n",
    "        dataloader: The DataLoader for the training data\n",
    "        criterion: The loss function\n",
    "        optimizer: The optimizer\n",
    "        num_epochs: The number of epochs to train\n",
    "    \"\"\"\n",
    "    for epoch in range(num_epochs):\n",
    "        # Set the model to training mode\n",
    "        model.train()\n",
    "        running_loss = 0.0\n",
    "        print(f'Epoch [{epoch+1}/{num_epochs}]')\n",
    "        for i, data in tqdm(enumerate(dataloader), desc='Training ...'):\n",
    "            data = data.to(device)\n",
    "\n",
    "            # Zero the parameter gradients\n",
    "            optimizer.zero_grad()\n",
    "            \n",
    "            # Forward pass\n",
    "            y = model(data[:, :-1, :])\n",
    "            # Compute the loss\n",
    "            loss = criterion(y, data[:, 1:, :])\n",
    "            # Backward pass and optimization\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "\n",
    "            # Print statistics\n",
    "            running_loss += loss.item()\n",
    "\n",
    "        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss/len(dataloader):.4f}')\n",
    "\n",
    "def test_model(model, dataloader, criterion1, criterion2, device='cuda'):\n",
    "    \"\"\"\n",
    "    Args:\n",
    "        model: The model to test\n",
    "        dataloader: The DataLoader for the test data\n",
    "        criterion: The loss function\n",
    "    \"\"\"\n",
    "    model.eval()\n",
    "    loss1_tested = []\n",
    "    loss2_tested = []\n",
    "    with torch.no_grad():\n",
    "        loss1_test = 0.0\n",
    "        loss2_test = 0.0\n",
    "        for data in tqdm(dataloader, desc='Testing ...'):\n",
    "            data = data.to(device)\n",
    "            y = model(data[:, :-1, :])\n",
    "            # 计算损失\n",
    "            loss = criterion1(y, data[:, 1:, :])\n",
    "            loss2 = criterion2(y, data[:, 1:, :])\n",
    "            # 累加损失\n",
    "            loss1_test += loss.item()\n",
    "            loss2_test += loss2.item()\n",
    "\n",
    "        # 计算平均损失\n",
    "        loss1_tested.append(loss1_test / len(dataloader))\n",
    "        loss2_tested.append(loss2_test / len(dataloader))\n",
    "    print(f'Test Loss: {loss1_tested[-1]:.4f}, Test Loss2: {loss2_tested[-1]:.4f}')\n",
    "    return loss1_tested, loss2_tested\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "e9a4a10c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 0it [00:00, ?it/s]"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 250.89it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/100], Loss: 30225.7136\n",
      "Epoch [2/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.48it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [2/100], Loss: 20016.6453\n",
      "Epoch [3/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 279.11it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [3/100], Loss: 18053.5046\n",
      "Epoch [4/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 272.74it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [4/100], Loss: 16738.6326\n",
      "Epoch [5/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 287.50it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [5/100], Loss: 17207.8722\n",
      "Epoch [6/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 263.18it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [6/100], Loss: 15518.6060\n",
      "Epoch [7/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 295.05it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [7/100], Loss: 15454.3435\n",
      "Epoch [8/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 263.58it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [8/100], Loss: 15033.8061\n",
      "Epoch [9/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 236.83it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [9/100], Loss: 14669.5480\n",
      "Epoch [10/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 252.99it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [10/100], Loss: 14359.9023\n",
      "Epoch [11/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 284.47it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [11/100], Loss: 14072.6731\n",
      "Epoch [12/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 287.97it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [12/100], Loss: 14004.7185\n",
      "Epoch [13/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.48it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [13/100], Loss: 13481.2089\n",
      "Epoch [14/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 267.71it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [14/100], Loss: 13959.0078\n",
      "Epoch [15/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 251.97it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [15/100], Loss: 13812.4054\n",
      "Epoch [16/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 292.07it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [16/100], Loss: 14082.9561\n",
      "Epoch [17/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 285.32it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [17/100], Loss: 14533.5255\n",
      "Epoch [18/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 277.62it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [18/100], Loss: 14002.1219\n",
      "Epoch [19/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.66it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [19/100], Loss: 13529.7245\n",
      "Epoch [20/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 283.29it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [20/100], Loss: 13180.4142\n",
      "Epoch [21/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 289.85it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [21/100], Loss: 12592.6586\n",
      "Epoch [22/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 241.34it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [22/100], Loss: 11900.1660\n",
      "Epoch [23/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 241.06it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [23/100], Loss: 12248.2102\n",
      "Epoch [24/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 262.41it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [24/100], Loss: 12945.9215\n",
      "Epoch [25/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.80it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [25/100], Loss: 12117.0769\n",
      "Epoch [26/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.45it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [26/100], Loss: 11695.2684\n",
      "Epoch [27/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.63it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [27/100], Loss: 11658.3764\n",
      "Epoch [28/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 249.19it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [28/100], Loss: 13724.1620\n",
      "Epoch [29/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 238.22it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [29/100], Loss: 12677.2900\n",
      "Epoch [30/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 278.24it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [30/100], Loss: 12403.5786\n",
      "Epoch [31/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 371.86it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [31/100], Loss: 12472.9977\n",
      "Epoch [32/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 370.99it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [32/100], Loss: 12258.4391\n",
      "Epoch [33/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 296.70it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [33/100], Loss: 12682.9650\n",
      "Epoch [34/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 236.43it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [34/100], Loss: 12324.4048\n",
      "Epoch [35/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 236.30it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [35/100], Loss: 11867.8430\n",
      "Epoch [36/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 237.24it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [36/100], Loss: 11989.3021\n",
      "Epoch [37/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 237.45it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [37/100], Loss: 11499.9418\n",
      "Epoch [38/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 237.97it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [38/100], Loss: 11574.8361\n",
      "Epoch [39/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 285.36it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [39/100], Loss: 11576.2396\n",
      "Epoch [40/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 269.71it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [40/100], Loss: 10995.3169\n",
      "Epoch [41/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:07, 229.07it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [41/100], Loss: 10913.7008\n",
      "Epoch [42/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 234.60it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [42/100], Loss: 10938.1243\n",
      "Epoch [43/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 251.61it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [43/100], Loss: 10671.2740\n",
      "Epoch [44/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 272.79it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [44/100], Loss: 11947.6646\n",
      "Epoch [45/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 237.97it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [45/100], Loss: 11109.7755\n",
      "Epoch [46/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 289.08it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [46/100], Loss: 11661.7590\n",
      "Epoch [47/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 290.62it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [47/100], Loss: 12352.8189\n",
      "Epoch [48/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.02it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [48/100], Loss: 11131.1812\n",
      "Epoch [49/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.14it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [49/100], Loss: 10572.7970\n",
      "Epoch [50/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 274.51it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [50/100], Loss: 10491.3227\n",
      "Epoch [51/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 255.30it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [51/100], Loss: 10470.8436\n",
      "Epoch [52/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.70it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [52/100], Loss: 10034.8550\n",
      "Epoch [53/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 292.61it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [53/100], Loss: 10370.8539\n",
      "Epoch [54/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.15it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [54/100], Loss: 9967.0568\n",
      "Epoch [55/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.73it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [55/100], Loss: 11003.1342\n",
      "Epoch [56/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.18it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [56/100], Loss: 22413.5799\n",
      "Epoch [57/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.43it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [57/100], Loss: 25291.0450\n",
      "Epoch [58/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 273.90it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [58/100], Loss: 16847.9908\n",
      "Epoch [59/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 284.39it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [59/100], Loss: 16181.1678\n",
      "Epoch [60/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.39it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [60/100], Loss: 15467.2845\n",
      "Epoch [61/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.69it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [61/100], Loss: 14486.9728\n",
      "Epoch [62/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 292.14it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [62/100], Loss: 13954.6905\n",
      "Epoch [63/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 278.04it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [63/100], Loss: 13917.9694\n",
      "Epoch [64/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 239.70it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [64/100], Loss: 14588.6218\n",
      "Epoch [65/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 267.05it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [65/100], Loss: 13902.6570\n",
      "Epoch [66/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 282.35it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [66/100], Loss: 13251.7664\n",
      "Epoch [67/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.24it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [67/100], Loss: 13057.1993\n",
      "Epoch [68/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 291.93it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [68/100], Loss: 13723.3199\n",
      "Epoch [69/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 267.90it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [69/100], Loss: 13031.1284\n",
      "Epoch [70/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 235.28it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [70/100], Loss: 12817.3637\n",
      "Epoch [71/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 238.29it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [71/100], Loss: 12774.7649\n",
      "Epoch [72/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 282.72it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [72/100], Loss: 12858.0500\n",
      "Epoch [73/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.96it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [73/100], Loss: 12493.1674\n",
      "Epoch [74/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 277.81it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [74/100], Loss: 12221.0087\n",
      "Epoch [75/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 295.95it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [75/100], Loss: 12115.1941\n",
      "Epoch [76/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 297.06it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [76/100], Loss: 11965.9343\n",
      "Epoch [77/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.98it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [77/100], Loss: 11798.4126\n",
      "Epoch [78/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.09it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [78/100], Loss: 12109.4847\n",
      "Epoch [79/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.77it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [79/100], Loss: 11772.2449\n",
      "Epoch [80/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 267.24it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [80/100], Loss: 11554.9746\n",
      "Epoch [81/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 280.15it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [81/100], Loss: 11462.1023\n",
      "Epoch [82/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 292.52it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [82/100], Loss: 11538.5626\n",
      "Epoch [83/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 294.80it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [83/100], Loss: 11327.6193\n",
      "Epoch [84/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 259.15it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [84/100], Loss: 11655.1870\n",
      "Epoch [85/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 237.02it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [85/100], Loss: 10928.9482\n",
      "Epoch [86/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:06, 264.29it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [86/100], Loss: 12336.2016\n",
      "Epoch [87/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 293.11it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [87/100], Loss: 11592.2170\n",
      "Epoch [88/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 280.31it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [88/100], Loss: 11711.6757\n",
      "Epoch [89/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 287.15it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [89/100], Loss: 13291.4688\n",
      "Epoch [90/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 288.01it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [90/100], Loss: 14259.6758\n",
      "Epoch [91/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 329.78it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [91/100], Loss: 13086.1858\n",
      "Epoch [92/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 369.87it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [92/100], Loss: 12387.2850\n",
      "Epoch [93/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 371.74it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [93/100], Loss: 12283.7881\n",
      "Epoch [94/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 371.38it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [94/100], Loss: 11826.9854\n",
      "Epoch [95/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 376.16it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [95/100], Loss: 11567.7609\n",
      "Epoch [96/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 373.67it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [96/100], Loss: 11649.3389\n",
      "Epoch [97/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:04, 373.70it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [97/100], Loss: 11370.0312\n",
      "Epoch [98/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 320.88it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [98/100], Loss: 11137.2321\n",
      "Epoch [99/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 292.20it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [99/100], Loss: 11780.8010\n",
      "Epoch [100/100]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Training ...: 1642it [00:05, 290.93it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [100/100], Loss: 13736.8623\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "\n",
    "model = SeqModel(input_size, hidden_size, seq_len, type_core = 'png', is_png_with_posEmb = False)\n",
    "model = model.to(device)\n",
    "# 定义损失函数和优化器\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 训练模型\n",
    "train_model(model, dataloader_train, criterion, optimizer, num_epochs=100, device=device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "74d51c4d",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Testing ...: 100%|██████████| 1642/1642 [00:02<00:00, 756.17it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test Loss: 12459.8434, Test Loss2: 16.6111\n",
      "[12459.843441292953] [16.61108833457027]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "# 测试模型\n",
    "mse, mae = test_model(model, dataloader_test, criterion, nn.L1Loss(), device=device)\n",
    "print(mse, mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d60c2990",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "env_jjk",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
